package com.cskaoyan.servlet;

import com.cskaoyan.bean.vo.BaseRespVo;
import com.cskaoyan.common.CommonServlet;
import com.cskaoyan.model.MarketAdmin;
import com.cskaoyan.service.AuthService;
import com.cskaoyan.service.LogService;
import com.cskaoyan.service.impl.AuthServiceImpl;
import com.cskaoyan.service.impl.LogServiceImpl;
import com.cskaoyan.utils.Constant;
import com.cskaoyan.utils.JacksonUtil;
import com.cskaoyan.utils.TransactionUtil;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author Pudding
 * @Date 2024/5/26 17:55
 */
@WebServlet("/admin/auth/*")
public class AdminAuthServlet extends CommonServlet {
    //service的使用
    AuthService authService = new AuthServiceImpl(); //登录+登录信息
    LogService logService = new LogServiceImpl(); //日志的service

    //1. login
    public BaseRespVo login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //开启事务
        TransactionUtil.startTransaction();

        //获取前端的POST请求中的JSON字符串
        String jsonStr = request.getReader().readLine();
        //将JSON字符串转换为Map
        Map<String, String> map = JacksonUtil.read(jsonStr, Map.class);
        //获取用户名和密码
        String username = map.get("username");
        String password = map.get("password");

        //登录，就是用户名和密码的比对
        //根据用户名查询数据库中的用户信息
        MarketAdmin admin = authService.findByUsername(username);

        //使用传入的密码和查询的用户信息中的密码进行比对，如果值一致，则登录成功，在session中提供标记
        if (password.equals(admin.getPassword())) { // 比较一致，就登录成功
            HttpSession session = request.getSession();//获取session

            //提供一个标记，同时提供了值（可以在其他请求访问的时候来获得这个值）
            //如果你通过session使用同一个key能够获取值，就认为之前登录成功
            session.setAttribute(Constant.ADMIN_KEY, admin.getId());

            //下面是提供的响应结果。使用一个Map来封装这些数据
            HashMap<String, String> adminInfo = new HashMap<>();
            adminInfo.put("nickName", admin.getUsername());
            adminInfo.put("avatat", admin.getAvatar());

            HashMap<String, Object> dataMap = new HashMap<>();
            dataMap.put("adminInfo", adminInfo);
            dataMap.put("token", session.getId()); //token这是使用SessionId

            logService.insertLog(request,1,"登录",true,"","");
            TransactionUtil.commit();

            //直接返回BaseRespVo对象，因为CommServlet判断如果返回值是BashRespVo类型的，会先转换为JSON字符串，然后写出，所以就不需要我们在这里转换为字符串再写出了
            return BaseRespVo.ok(dataMap);
        } else {
            //比较不一致，就认为登录失败
            logService.insertLog(request,1,"登录",false,"用户账户或密码不正确","");
            TransactionUtil.commit();
            return BaseRespVo.fail("用户账户或密码不正确", 605);
        }

    }

    //2. logout：这个是登录成功之后才能访问
    public BaseRespVo logout(HttpServletRequest request, HttpServletResponse response) {
        TransactionUtil.startTransaction();

        //退出操作
        request.getSession().invalidate();

        //添加日志
        logService.insertLog(request,1,"退出", true, "","");

        //关闭事务
        TransactionUtil.commit();
        return BaseRespVo.fail("成功",0);
    }

    //3. info：获得当前登录用户信息
    public BaseRespVo info(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession(); //当前用户的session对象
        //在Session中拿到，再访问/admin/auth/login这里登录成功的时候存入的信息
        Integer adminId = (Integer) session.getAttribute(Constant.ADMIN_KEY);

        //然后根据adminId做对应的查询
        MarketAdmin admin = authService.findById(adminId);

        if (admin != null){
            HashMap<String, Object> data = new HashMap<>();
            data.put("avatar", admin.getAvatar());
            data.put("name", admin.getUsername());
            data.put("perms", Arrays.asList("*")); //将数组转换为集合
            data.put("roles",admin.getRoleIds());//这里我们可以使用typehandler在MarketAdmin中将roleIds这个成员变量直接改为Integer[],提供Integer[]的typehandle
            return BaseRespVo.ok(data);
        }else {
            //长时间没有登录，之后adminId失效
            return BaseRespVo.fail("获取用户信息失败", 605);
        }
    }

    //4. modify
    public BaseRespVo modify(HttpServletRequest request, HttpServletResponse response) {
        // 写修改业务代码
        return BaseRespVo.msg("修改成功");
    }

    //5. remove
    public BaseRespVo remove(HttpServletRequest request, HttpServletResponse response) {
        // 写删除业务代码
        return BaseRespVo.msg("删除成功");
    }

}
